package org.hit.burkun.entities.realtions;

import javax.annotation.Nonnull;

import org.hit.burkun.entities.Entity;

public class BaseRealtion {
	/**
	 * 标记的二元关系的类型
	 * 
	 * @author burkun
	 * 
	 */
	public enum TYPE {
		// 这里默认都是双向
		DO_GO("do_go"), GO_DO("go_do"), DO_HP("do_hp"), HP_DO("hp_do"), GO_HP(
				"go_hp"), HP_GO("hp_go"), GOMF_GOBP("gomf_gobp"), GOBP_GOMF(
				"gobp_gomf"), GOCC_GOMF("gocc_gomf"), GOMF_GOCC("gomf_gocc"), GOBP_GOCC(
				"gobp_gocc"), GOCC_GOBP("gocc_gobp"), GENE_DISEASE(
				"gene_disease"), DISEASE_GENE("disease_gene"), GENE_GENE(
				"gene_gene"), DISEASE_DISEASE("disease_disease"), DO_DO("do_do"), GO_GO(
				"go_go"), HP_HP("hp_hp"), DO_GENE("do_gene"), HP_GENE("hp_gene"), GO_GENE(
				"go_gene"), GENE_DO("gene_do"), GENE_GO("gene_go"), GENE_HP(
				"gene_hp"), UNPORT_UNPORT("uniport_uniport");
		@Nonnull
		private final String tag;

		TYPE(@Nonnull String tag) {
			this.tag = tag;
		}

		/** @return tag */
		@Nonnull
		public String getTag() {
			return tag;
		}

		public String getReverseTag() {
			String[] line = tag.split("_");
			return line[1] + "_" + line[0];
		}

		@Override
		public String toString() {
			return tag;
		}

		/**
		 * 通过string 返回类型，如果不存在那么返回null
		 * 
		 * @param tag
		 * @return BaseRelation.TYPE or null
		 */
		public static TYPE getTypeByTag(String tag) {
			if (tag.equals(DO_DO.getTag()))
				return DO_DO;
			if (tag.equals(HP_DO.getTag()))
				return HP_DO;
			if (tag.equals(GO_HP.getTag()))
				return GO_HP;
			if (tag.equals(GOMF_GOBP.getTag()))
				return GOMF_GOBP;
			if (tag.equals(GOMF_GOCC.getTag()))
				return GOMF_GOCC;
			if (tag.equals(GOBP_GOCC.getTag()))
				return GOBP_GOCC;
			if (tag.equals(GENE_DISEASE.getTag()))
				return GENE_DISEASE;
			if (tag.equals(DISEASE_GENE.getTag()))
				return DISEASE_GENE;
			if (tag.equals(GENE_GENE.getTag()))
				return GENE_GENE;
			if (tag.equals(DISEASE_DISEASE.getTag()))
				return DISEASE_DISEASE;
			if (tag.equals(DO_GO.getTag()))
				return DO_GO;
			if (tag.equals(GO_GO.getTag()))
				return GO_GO;
			if (tag.equals(HP_HP.getTag()))
				return HP_HP;
			if (tag.equals(DO_GENE.getTag()))
				return DO_GENE;
			if (tag.equals(HP_GENE.getTag()))
				return HP_GENE;
			if (tag.equals(GO_GENE.getTag()))
				return GO_GENE;
			if (tag.equals(UNPORT_UNPORT.getTag()))
				return UNPORT_UNPORT;

			if (tag.equals(GO_DO.getTag()))
				return GO_DO;
			if (tag.equals(DO_HP.getTag()))
				return DO_HP;
			if (tag.equals(HP_GO.getTag()))
				return HP_GO;
			if (tag.equals(GOBP_GOMF.getTag()))
				return GOBP_GOMF;
			if (tag.equals(GOCC_GOMF.getTag()))
				return GOCC_GOMF;
			if (tag.equals(GOCC_GOBP.getTag()))
				return GOCC_GOBP;
			if (tag.equals(GENE_DO.getTag()))
				return GENE_DO;
			if (tag.equals(GENE_GO.getTag()))
				return GENE_GO;
			if (tag.equals(GENE_HP.getTag()))
				return GENE_HP;
			return null;
		}
	};

	private boolean isDirect = false;
	// 关系的描述，如致病，诱发等
	private String desc;
	private TYPE type;
	private Entity ent1;
	private Entity ent2;
	private String dbid; // 数据库来源
	// 计算置信度
	private Double confidscore = 0.0;
	// 计算方式
	private String calcMethod;
	// 证据集合urls
	private String evidenceUrls;
	// 其它字段
	private Object otherData;

	/**
	 * 构造出一条BaseRealtion，其中Entity现在只用到了primary id，所以可以进行投机取巧，先把所有的pid查出来就ok了
	 * 
	 * @param ent1
	 *            term1
	 * @param ent2
	 *            term2
	 * @param isDirect
	 * @param type
	 */
	public BaseRealtion(Entity ent1, Entity ent2, boolean isDirect, TYPE type) {
		this.isDirect = isDirect;
		this.type = type;
		this.ent1 = ent1;
		this.ent2 = ent2;
	}

	@Override
	public String toString() {
		if (this.isDirect) {
			return this.ent1.getDbid() + "->" + ent2.getDbid();
		}
		return this.ent1.getDbid() + "<->" + ent2.getDbid() + "\n";
	}

	@Override
	public boolean equals(Object obj) {
		if (obj instanceof BaseRealtion) {
			BaseRealtion r = (BaseRealtion) obj;
			if (r.getEnt1().equals(this.ent1) && r.getEnt2().equals(this.ent2)
					&& this.type == r.getType()) {
				return true;
			}
		}
		return false;
	}

	/**
	 * @return 每条边的置信度
	 */
	public Double getConfidscore() {
		return confidscore;
	}

	public void setConfidscore(Double confidscore) {
		this.confidscore = confidscore;
	}

	public String getCalcMethod() {
		return calcMethod;
	}

	public void setCalcMethod(String calcMethod) {
		this.calcMethod = calcMethod;
	}

	public boolean isDirect() {
		return isDirect;
	}

	public void setDirect(boolean isDirect) {
		this.isDirect = isDirect;
	}

	public String getDesc() {
		return desc;
	}

	public void setDesc(String desc) {
		this.desc = desc;
	}

	public Entity getEnt1() {
		return ent1;
	}

	public void setEnt1(Entity ent1) {
		this.ent1 = ent1;
	}

	public Entity getEnt2() {
		return ent2;
	}

	public void setEnt2(Entity ent2) {
		this.ent2 = ent2;
	}

	public void setType(TYPE type) {
		this.type = type;
	}

	public TYPE getType() {
		return type;
	}

	public Entity getToEntity() {
		return ent1;
	}

	public Entity getFromEntiy() {
		return ent2;
	}

	public String getDbid() {
		return dbid;
	}

	public void setDbid(String dbid) {
		this.dbid = dbid;
	}

	public String getEvidenceUrls() {
		return evidenceUrls;
	}

	public void setEvidenceUrls(String evidenceUrls) {
		this.evidenceUrls = evidenceUrls;
	}

	public Object getOtherData() {
		return otherData;
	}

	public void setOtherData(Object otherData) {
		this.otherData = otherData;
	}

}
